use common_uu::arg::get_arg;
use common_uu::my_request::{post_json, get_json};
use common_uu::IResult;
use serde_json::Map;

pub fn run() {
    for i in 0.. {
        let api_k = format!("api[{}]", i);
        let url = match get_arg(format!("{}.url", api_k)) {
            Some(v) => v,
            None => break,
        };

        debug!("url: {}", url);

        let method = get_arg(format!("{}.method", api_k)).unwrap_or_default();
        let body = get_arg(format!("{}.body", api_k)).unwrap_or_default();
        let response = get_arg(format!("{}.response", api_k)).unwrap_or_default();

        match method.to_lowercase().as_str() {
            "post" => {
                let body = if body == "" { serde_json::Value::Null } else {
                    match serde_json::from_str(&body) {
                        Ok(v) => v,
                        Err(e) => {
                            error!("url: {}, error:", e);
                            continue;
                        }
                    }
                };

                let result = match post_json::<Map<String, serde_json::Value>>(url.clone(), body){
                    Ok(v) => v,
                    Err(e) => {
                        error!("url: {}, error: {}", url, e);
                        continue;
                    }
                };

                if let Err(e) = check_data(result.clone(), response) {
                    error!("url: {}, response: {:?}, error: {:?}", url, result, e);
                    continue;
                }
                info!("post_json, url: {}, res: {:?}", url, &result);
            }
            "get" => {
                let result = match get_json::<Map<String, serde_json::Value>>(url.clone()){
                    Ok(v) => v,
                    Err(e) => {
                        error!("url: {}, error: {}", url, e);
                        continue;
                    }
                };
                if let Err(e) = check_data(result.clone(), response) {
                    error!("url: {}, response: {:?}, error: {:?}", url, result, e);
                    continue;
                }
                info!("get_json, url: {}, res: {:?}", url, &result);
            }
            _ => {
                error!("url: {}, method not supper", url)
            }
        }
    }
}

fn check_data(json_v: Map<String, serde_json::Value>, cleck_res: String) -> IResult<()> {
    let cleck_res = serde_json::from_str::<Map<String, serde_json::Value>>(&cleck_res)?;
    for (k, v) in &cleck_res {
        if v != json_v.get(k).unwrap_or_else(|| &serde_json::Value::Null) {
            Err(serde_json::json!(json_v).to_string())?;
        }
    }
    Ok(())
}